using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms;
using Camalon.Drawing;

namespace Camalon.Drawing.Design
{
	/// <summary>
	/// Summary description for HeaderControl.
	/// </summary>
    [ToolboxItem(false)]
    public class HeaderControl : System.Windows.Forms.UserControl
	{
		protected internal event ValueChangeEventHandler SelectedIndexChanged;
		protected internal event EventHandler CloseClick;
		private	string[]	_pages			= new string[]{};
		private const int	_offsetTop		= 4;
		private const int	_offsetBotom	= 2;
		private int			_selected		= 0;

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		private Camalon.Drawing.Design.HeaderControl.CloseButton _closeButton;





		public HeaderControl()
		{
			SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true);
			SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
			SetStyle(System.Windows.Forms.ControlStyles.ResizeRedraw, true);
			SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true);

			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();
			_closeButton.Click +=new EventHandler(CloseButton_Click);

			// TODO: Add any initialization after the InitComponent call
		}


		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if( components != null )
					components.Dispose();
			}
			base.Dispose( disposing );
		}



		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this._closeButton = new Camalon.Drawing.Design.HeaderControl.CloseButton();
            this.SuspendLayout();
            // 
            // _closeButton
            // 
            this._closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this._closeButton.Location = new System.Drawing.Point(884, 1);
            this._closeButton.Name = "_closeButton";
            this._closeButton.Size = new System.Drawing.Size(16, 16);
            this._closeButton.TabIndex = 0;
            // 
            // HeaderControl
            // 
            this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(245)))));
            this.Controls.Add(this._closeButton);
            this.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.Name = "HeaderControl";
            this.Size = new System.Drawing.Size(900, 18);
            this.ResumeLayout(false);

		}
		#endregion

		
		protected bool ShouldSerializePages()
		{
			return _pages.Length > 0;
		}

		public string[] TabPages
		{
			get{ return _pages;}
			set
			{
				try
				{
					this.SuspendLayout();

					if( value == null) _pages = new string[]{};
					else _pages = value; 

					ResetTabPages(true);
				}
				finally
				{
					this.ResumeLayout( true );
				}

			}

		}


		[DefaultValue(0)]
		public int Selected
		{
			get{ return _selected;}
			set
			{ 
				if( _selected == value) return;
				int oldValue = _selected;
				if( _pages.Length == 0) _selected = 0;
				else if( value < 0) value = 0;
				else if( value > _pages.Length-1) value = _pages.Length-1;

				_selected = value;
				
				ResetTabPages(false);
				
				if( this.SelectedIndexChanged != null) SelectedIndexChanged( this, new ValueChangeEventArgs(oldValue, _selected) );
			}
		}

		private void CloseButton_Click(object sender, EventArgs e)
		{
			if( this.CloseClick != null) this.CloseClick( this, new EventArgs());
		}
	
		private void HeaderButton_MouseDown(object sender, MouseEventArgs e)
		{
			for( int i = 1; i < this.Controls.Count; i++)
			{
				HeaderButton hb = this.Controls[i] as HeaderButton;
				if( hb != null && hb == sender) this.Selected = i-1;
			}
		}


		public void ResetTabPages( bool recreate )
		{
			this.SuspendLayout();

			try
			{
				int nextLocation = 5;

				if( recreate)
				{
					for( int i = 1; i < this.Controls.Count; i++)
					{
						HeaderButton hb = this.Controls[i] as HeaderButton;
						if( hb != null) 
							hb.MouseDown -=new MouseEventHandler(HeaderButton_MouseDown);
					}

					this.Controls.Clear();
					this.Controls.Add( _closeButton );

					for( int i = 0; i < _pages.Length; i++)
					{
						string s = _pages[i];
						HeaderButton hb = new HeaderButton(this);
						hb.MouseDown +=new MouseEventHandler(HeaderButton_MouseDown);
						hb.Index = i;
						hb.SuspendLayout();
						hb.Font = base.Font;

						hb.SelectedButton = i == _selected;
						
						hb.Text = s;

						hb.Location = new Point(nextLocation,_offsetTop);	
						hb.Width	= hb.MeasureTextSize.Width;
						hb.Height	= this.Height-_offsetBotom - _offsetTop;

						this.Controls.Add( hb );

						hb.ResumeLayout(true);
						nextLocation+= hb.Width;


					}
				}
				else//First item is the close button
					for( int i = 1; i < this.Controls.Count; i++)
					{
						HeaderButton hb = this.Controls[i] as HeaderButton;
						if( hb == null) continue;
						hb.Index = i-1;

						hb.SuspendLayout();
						
						hb.Font = base.Font;
						hb.SelectedButton = (i-1)== _selected;

						hb.Location = new Point(nextLocation,_offsetTop);


						hb.Width	= hb.MeasureTextSize.Width;
						hb.Height	= this.Height-_offsetBotom - _offsetTop;

						nextLocation+= hb.Width ;
						hb.ResumeLayout(true);
					}
			}
			finally
			{
				this.ResumeLayout(true);
			}
		}

		protected override void OnResize(EventArgs e)
		{
			base.OnResize (e);

			int nextLocation = 5;

			foreach( Control c in this.Controls )
			{

				HeaderButton hb = c as HeaderButton;
				if( hb != null) 
				{
					
					hb.Height = this.Height -_offsetBotom - _offsetTop;

					nextLocation += hb.Width;
					if( nextLocation > this.Width - 20) hb.Visible = false;
					else hb.Visible = true;
				}
				
			}


			
			this.Invalidate(true);
		}


		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint (e);

			Graphics g = e.Graphics;
			Rectangle bounds = this.ClientRectangle;
			Point leftBottom = new Point( bounds.Left, bounds.Bottom);
			Point rightBottom = new Point( bounds.Right, bounds.Bottom);

			Pen pen = SystemPens.Control.Clone() as Pen;
			pen.Width = 2* _offsetBotom;
			g.DrawLine( pen, leftBottom, rightBottom);

		}



		private class HeaderButton : System.Windows.Forms.Control
		{

			private bool _selectedButton = false;

			protected internal int Index = -1;
			private HeaderControl _parent = null;
			public HeaderButton(HeaderControl parent)
			{
				_parent = parent;

				SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true);
				SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
				SetStyle(System.Windows.Forms.ControlStyles.ResizeRedraw, true);
				SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true);

			}


			[DefaultValue( false)]
			public bool SelectedButton
			{
				get{ return _selectedButton;}
				set
				{
					_selectedButton = value;

					if( value)
					{
						Font font = new Font(base.Font.FontFamily, base.Font.Size,FontStyle.Bold);
						base.Font= font;
					}
				
					this.Invalidate();
				}
			}

		

			public Size MeasureTextSize
			{
				get
				{
					string text = base.Text;
					if( text.Length == 0) return this.Size;

					Graphics g = this.CreateGraphics();
					try
					{
						Size size = Size.Round(g.MeasureString( text, base.Font, new PointF(0,0), TextFormat));
						size.Width += 6;
						return size;
					}
					finally
					{
						g.Dispose();
					}
				}

			}


			private StringFormat TextFormat
			{
				get
				{
					StringFormat sf = StringFormat.GenericDefault.Clone() as StringFormat;
					sf.FormatFlags = StringFormatFlags.NoWrap| StringFormatFlags.MeasureTrailingSpaces;
					sf.Trimming = StringTrimming.None;
					sf.Alignment = StringAlignment.Center;
					sf.LineAlignment = StringAlignment.Center;

					return sf;
				}
			}


			protected override void OnPaint(PaintEventArgs pe)
			{
				base.OnPaint( pe);

				Graphics g = pe.Graphics;
		
				GraphicsContainer c = g.BeginContainer();
				try
				{
					bool enabled = base.Enabled;

					Rectangle bounds = ClientRectangle;

					if( _selectedButton ) 
						g.FillRectangle( SystemBrushes.Control, bounds);
					else
						g.FillRectangle( new SolidBrush(this.BackColor), bounds );// ( SystemBrushes.Info, bounds);

					Color textColor = SystemPens.ControlDarkDark.Color;
					if( _selectedButton ) textColor = SystemPens.ControlText.Color;
 
					if( this.Index != _parent.Selected - 1)
					{
						Point rightTop = new Point( bounds.Right, bounds.Top);
						Point rightBottom = new Point( bounds.Right, bounds.Bottom - 2 );
						if( _selectedButton) rightBottom.Y+=2;
						Pen pen = new Pen( textColor, 2f);
						g.DrawLine( pen, rightTop, rightBottom);
					}

					string s = this.Text;
					Font font = this.Font;
					StringFormat sf = TextFormat;
					Brush textBrush = new SolidBrush( textColor );
					g.DrawString( s, font,textBrush, bounds, sf);

				}
				finally
				{
					g.EndContainer( c);
				}
			}


		}


		private class CloseButton: System.Windows.Forms.Control
		{
			public CloseButton()
			{
				SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true);
				SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
				SetStyle(System.Windows.Forms.ControlStyles.ResizeRedraw, true);
				SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true);

			}

			private bool _mouseEntered = false;
			protected override void OnMouseEnter(EventArgs e)
			{
				_mouseEntered = true;
				base.OnMouseEnter (e);
				Invalidate(true);
			}

			protected override void OnMouseLeave(EventArgs e)
			{
				_mouseEntered = false;
				base.OnMouseLeave (e);
				Invalidate(true);
			}

		
			private bool _mouseDown = false;
			protected override void OnMouseDown(MouseEventArgs e)
			{
				_mouseDown = true;
				base.OnMouseDown (e);
				Invalidate(true);
			}

			protected override void OnMouseUp(MouseEventArgs e)
			{
				_mouseDown = false;
				base.OnMouseUp (e);
				Invalidate(true);
			}



			protected override void OnPaint(PaintEventArgs e)
			{
				base.OnPaint (e);


				Graphics g = e.Graphics;
		
				GraphicsContainer c = g.BeginContainer();
				try
				{
					bool enabled = base.Enabled;

					Rectangle bounds = this.ClientRectangle;
					g.FillRectangle( new SolidBrush(this.BackColor), bounds );//( SystemBrushes.Info, bounds);


					bounds.Inflate( -4,-4);

					bounds.X-=1;
					bounds.Y-=1;

					if( _mouseEntered && _mouseDown)//Clicking
					{
						bounds.X+=1;
						bounds.Y+=1;

					}



					Point leftTop		= new Point( bounds.Left, bounds.Top);
					Point rightBottom	= new Point( bounds.Right, bounds.Bottom);
					Point leftBottom	= new Point( bounds.Left, bounds.Bottom);
					Point rightTop		= new Point( bounds.Right, bounds.Top);

					Color textColor = enabled ? SystemPens.ControlText.Color : SystemPens.GrayText.Color;
					Pen pen = new Pen( textColor, 2f);
					pen.LineJoin = LineJoin.Round;

					//Draw Cross----------------------------
					g.SmoothingMode = SmoothingMode.AntiAlias;
					Color crosPenColor = enabled ? SystemColors.ControlDarkDark : SystemColors.ControlLightLight;
					using( Pen crossPen = new Pen( crosPenColor, 2f) )
					{
//						g.DrawLine( pen, leftTop, rightBottom);
//						g.DrawLine( pen, leftBottom, rightTop);
						crossPen.StartCap = LineCap.Round;
						crossPen.EndCap = LineCap.Round;
						g.DrawLine( crossPen, leftTop, rightBottom);
						g.DrawLine( crossPen, leftBottom, rightTop);
					}
					g.SmoothingMode = SmoothingMode.Default;

					bounds		= this.ClientRectangle;
					leftTop		= new Point( bounds.Left, bounds.Top);
					rightBottom = new Point( bounds.Right, bounds.Bottom);
					leftBottom	= new Point( bounds.Left, bounds.Bottom);
					rightTop	= new Point( bounds.Right, bounds.Top);

					if( _mouseEntered && _mouseDown)//Clicking
					{	
						//Draw TopLeft shadow
						pen.Width = 1;
						pen.Color =  SystemPens.ControlText.Color;
						g.DrawLine( pen, leftBottom, leftTop);
						g.DrawLine( pen, leftTop, rightTop);

						// Draw BottomRight shadow
						pen.Color =  SystemPens.Control.Color;
						pen.Width = 2;
						g.DrawLine( pen, leftBottom, rightBottom);
						g.DrawLine( pen, rightBottom, rightTop);

					}

					if( _mouseEntered && !_mouseDown)//MouseOver
					{  
						//Draw TopLeft shadow
						pen.Width = 1;
						pen.Color =  SystemPens.Control.Color;
						g.DrawLine( pen, leftBottom, leftTop);
						g.DrawLine( pen, leftTop, rightTop);

						// Draw BottomRight shadow
						pen.Width = 2;
						pen.Color =  SystemPens.ControlText.Color;
						g.DrawLine( pen, leftBottom, rightBottom);
						g.DrawLine( pen, rightBottom, rightTop);

					}



				}
				finally
				{
					g.EndContainer( c);
				}
			}


		}


	}
}
